<script setup lang="ts">
import { extractAttrsEvent } from '@/core/utils/install';
import { ElSelect, selectProps } from 'element-plus';
import { PropType } from 'vue';
import { IOptionItem } from './types';

defineOptions({ name: 'ProSelect' });

const modelValue = defineModel<typeof selectProps.modelValue.type>();

const label = defineModel('label', {
  type: [String, Number] as PropType<string | number>,
  default: '',
});
const value = defineModel('value', {
  type: String as PropType<string>,
  default: '',
});

const props = defineProps({
  ...selectProps,
  options: {
    type: Array as PropType<IOptionItem[]>,
    default: () => [],
  },
  optionValue: { type: String, default: 'value' },
  optionLabel: { type: String, default: 'label' },
  hiddenValue: { type: Boolean, default: false },
});

const { options = [], optionValue = 'value', optionLabel = 'label', hiddenValue = false, ...rest } = props;

const showValue = computed(() => !hiddenValue);

watch(modelValue, (data) => {
  if (props.multiple) {
    const matchs = (data as any[])?.map((v) => options.find((item) => item[optionValue] === v));
    label.value = matchs?.map((v) => v?.[optionLabel])?.join(',') ?? '';
    value.value = matchs?.map((v) => v?.[optionValue])?.join(',') ?? '';
    return;
  }
  label.value = options.find((v) => v[optionValue] === data)?.[optionLabel] ?? '';
  value.value = options.find((v) => v[optionValue] === data)?.[optionValue] ?? '';
});

const isNestOptions = computed(() => options.every((item) => Array.isArray(item.options)));

const attrs = useAttrs();
const event = extractAttrsEvent(attrs);

const slots = useSlots();
</script>

<template>
  <el-select v-bind="{ ...rest, ...event }" v-model="modelValue" placeholder="请选择">
    <template v-for="(slot, name) in slots" #[name]>
      <slot :name="name" v-bind="slot" />
    </template>
    <template v-if="!multiple" #label>
      <slot name="label">{{ label }}</slot>
    </template>
    <slot name="default">
      <template v-if="isNestOptions">
        <el-option-group v-for="group of options" :key="group[optionLabel]" :label="String(group[optionLabel])">
          <el-option
            v-for="item in group.options"
            :key="item[optionValue]"
            :label="item[optionLabel]"
            :value="item[optionValue]"
            :disabled="item.disabled"
          >
            <template v-if="showValue">{{ item[optionValue] }}-{{ item[optionLabel] }}</template>
          </el-option>
        </el-option-group>
      </template>
      <template v-else>
        <el-option
          v-for="item in options"
          :key="item[optionValue]"
          :label="item[optionLabel]"
          :value="item[optionValue]"
          :disabled="item.disabled"
        >
          <template v-if="showValue">{{ item[optionValue] }}-{{ item[optionLabel] }}</template>
        </el-option>
      </template>
    </slot>
  </el-select>
</template>

<style lang="scss" scoped></style>
